<?php
// +----------------------------------------------------------------------
// | 事件日志服务层
// +----------------------------------------------------------------------
// | 主要服务于事件日志数据处理
// +----------------------------------------------------------------------
// | 错误编码头 206xxx
// +----------------------------------------------------------------------
namespace common\service;

use common\model\TenantUserModel;
use common\model\UserModel;
use teamones\Request;

class EventLogService
{
    // 错误信息
    protected $errorMsg = '';

    /**
     * 获取错误信息
     * @return string
     */
    public function getError()
    {
        return $this->errorMsg;
    }

    /**
     * 记录到Event服务器
     * @param $data
     * @param $controllerMethod
     * @return array|\Yurun\Util\YurunHttp\Http\Response
     */
    protected function postToServer($data, $controllerMethod)
    {

        $response = Request::connection()->setServerHost('teamones-log')
            ->setRoute($controllerMethod)
            ->setBody($data)
            ->setMethod('POST')
            ->request();

        return $response;
    }

    /**
     * 记录事件日志
     * @param $param
     */
    public function create($param)
    {
//        // 记录到Event服务器
//        try {
//            $this->postToServer(['data' => $param], "log/add");
//        } catch (\Throwable $e) {
//            trace("postToServer got exception", "ERR");
//            trace("##########################", "ERR");
//            trace($e->getMessage(), 'ERR');
//            trace($e->getCode(), 'ERR');
//            trace($e->getTraceAsString(), 'ERR');
//            trace("##########################", "ERR");
//        }
        // 处理租户更新状态
        try {
            $tenantUpdateEvents = array_filter($param, function ($item) {
                return isset($item['module_code']) && $item['module_code'] == 'tenant' && isset($item['operate']) && $item['operate'] == 'update';
            });
            $this->handleTenantUpdateRole($tenantUpdateEvents);
        } catch (Throwable $e) {
            trace("handleTaskStatusUpdate got exception", 'ERR');
            trace(format_exception_info($e), 'ERR');
        }
    }

    /**
     * 写入交易记录日志
     * @param $param
     */
    public function writeTransactionRecords($param)
    {
        // 记录到Event服务器
        try {
            $this->postToServer($param, "transaction_records/add");
        } catch (\Throwable $e) {
            trace("postToServer got exception", "ERR");
            trace("##########################", "ERR");
            trace($e->getMessage(), 'ERR');
            trace($e->getCode(), 'ERR');
            trace($e->getTraceAsString(), 'ERR');
            trace("##########################", "ERR");
        }
    }

    /**
     * 监听租户更新权限
     * @param $tenantUpdateEvents
     * @return void
     */
    public function handleTenantUpdateRole($tenantUpdateEvents)
    {
        foreach ($tenantUpdateEvents as $item) {
            try {
                $record = $item['record'];
                if (!array_key_exists("role", $record['data']['old']) || !array_key_exists("role", $record['data']['new'])) {
                    return;
                }
                $tenantUserModel = model(TenantUserModel::class);
                $tenantUserList = $tenantUserModel->where(['tenant_id' => $record['primary_id'], 'status' => 'active'])->column('user_id');
                $channelList = model(UserModel::class)->where(['id' => ['IN', implode(',', $tenantUserList)]])->column('channel');
                $centrifugalService = CentrifugalService::getInstance();
                $centrifugalService->broadcast($channelList, [
                    'event_key' => "setting_tenant_role",
                    'event_data' => [
                        "role" => $record['data']['new']['role'],
                        "tenant_id" => $record['primary_id']
                    ]
                ]);
                // 获取当前租户的所有项目
                $projectList = Request::connection()
                    ->setHeader([
                        'X-Userinfo' => \request()->getXUserInfo(),
                    ])
                    ->setServerHost('teamones-saas')
                    ->setRoute('project/get_projects')
                    ->setBody([
                        'param' => [
                            'fields' => 'id,name,type,json',
                            'filter' => [
                                'tenant_id' => $record['primary_id'],
                            ]
                        ]
                    ])
                    ->setMethod('POST')
                    ->request()['data'];
                if (empty($projectList)) {
                    return;
                }
                $updateOutsource = [];
                if ($record['data']['new']['role'] == 'to_tenant') { // 乙方
                    // 获取外包项目的所有ID，更改现有状态并保留原有状态
                    foreach ($projectList as &$item) {
                        $item['json'] = json_decode($item['json'], true);
                        if ($item['type'] == 'insource') {
                            if ($item['json']['project_status'] == 3) {
                                continue;
                            }
                            $tmpUpdateOutsource['id'] = $item['id'];
                            $tmpUpdateOutsource['json'] = [
                                'project_status' => 3,
                                'old_project_status' => $item['json']['project_status'],
                            ];
                            $updateOutsource[] = $tmpUpdateOutsource;
                        }
                    }
                } else if ($record['data']['new']['role'] == 'from_tenant') { // 甲方
                    // 将原有状态恢复，如果没有保存老状态就直接跳过
                    foreach ($projectList as &$item) {
                        $item['json'] = json_decode($item['json'], true);
                        if ($item['type'] == 'insource' && !empty($item['json']['old_project_status']) && $item['json']['project_status'] == 3) {
                            $tmpUpdateOutsource['id'] = $item['id'];
                            $tmpUpdateOutsource['json'] = [
                                'project_status' => $item['json']['old_project_status'],
                                'old_project_status' => ''
                            ];
                            $updateOutsource[] = $tmpUpdateOutsource;
                        }
                    }
                }
                if ($updateOutsource) {
                    Request::connection()
                        ->setHeader([
                            'X-Userinfo' => \request()->getXUserInfo(),
                        ])
                        ->setServerHost('teamones-saas')
                        ->setRoute('project/batch_update')
                        ->setBody([
                            'data_list' => $updateOutsource,
                            'throw_no_data_change_exception' => 'no'
                        ])
                        ->setMethod('POST')
                        ->request();
                }
            } catch (\Throwable $e) {
                trace(format_exception_info($e), 'ERR');
            }
        }
    }

}
